package com.iflytek.uoamp.agent.monitor.find;

import com.iflytek.uoamp.agent.common.constants.CommonConstants;
import com.iflytek.uoamp.agent.core.sender.monitorsender.monitorinterface.IItem;
import com.iflytek.uoamp.agent.core.sender.monitorsender.requestObj.SendResponse;
import com.iflytek.uoamp.agent.core.sender.monitorsender.requestObj.SendResponse.RESPONSESTATUS;
import com.iflytek.uoamp.agent.core.sender.monitorsender.responseObj.Program;
import com.iflytek.uoamp.agent.monitor.find.imp.FindLibMonitorItem;
import com.iflytek.uoamp.agent.monitor.find.imp.FindMonitorItemByShell;
import com.iflytek.uoamp.agent.monitor.find.imp.FindWinMonitorItem;
import com.iflytek.uoamp.agent.monitor.find.imp.baseitem.FindBaseMonitorItemAbs;
import com.iflytek.uoamp.agent.monitor.find.imp.baseitem.FindBaseMonitorItemFactory;
import com.iflytek.uoamp.agent.monitor.find.obj.ProgramObj;
import com.iflytek.uoamp.agent.monitor.mcagent.MCAgentConfig;
import com.iflytek.uoamp.agent.monitor.mcagent.MCAgentMain;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;

import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

/**
 * finder main thread . init filter and run add thread
 * */
public class FinderThread extends Thread {

	// this is base finder , when AllowHead change,it must be reload
	private static FindBaseMonitorItemAbs findMonitor = FindBaseMonitorItemFactory.getBaseMonitorItemFinder(CommonConstants.ALLOW_PATH);

	//this is lib finder ,if get lib info .it should be add to this find
	private static FindLibMonitorItem findLib = new FindLibMonitorItem();
	
	
	/**
	 * 发送发现出来的组件;
	 * */
	private void sendFindResult(Filter filter,List<IItem> sendProgram) {
		//判断使用哪种方式发送
		SendResponse instance = sendProgram(sendProgram);
		
		if (instance == null) {
			return ;
		}
	}



	/**
	 * @param sendProgram
	 * @return SendResponse
	 */
	private SendResponse sendProgram(List<IItem> sendProgram) {
		SendResponse instance = null;
		if (MCAgentMain.getSenderClient().getConfig().isUseHttp()) {
			Logger.getRootLogger().info("send item by http! ");
			if (sendProgram != null && sendProgram.size() != 0) {
				Object result = MCAgentMain.getSenderClient().sendBatchByHttp(sendProgram);
				if(result.toString().contains("OK")){
					instance = new SendResponse();
					instance.setStatus(RESPONSESTATUS.OK);
				}else{
					instance = new SendResponse();
					instance.setStatus(RESPONSESTATUS.ERROR);
				}
			}
		} else {
			Object result = MCAgentMain.getSenderClient().sendBatchBySafe(sendProgram);
			Logger.getRootLogger().info("send item item by netty! ");
			if (result != null && result instanceof SendResponse) {
				instance = (SendResponse) result;
			}
		}
		return instance;
	}

	/**
	 * 运行发现脚本...
	 * @param finders
	 * @param filter
	 * @param trust
	 * @return
	 */
	private List<IItem> runFinder(List<Finder> finders, Filter filter, TrustJudgement trust) {
		List<IItem> sendProgram = new LinkedList<IItem>();
		for (Finder curFinder : finders) {
			Logger.getRootLogger().info("run " + curFinder.getClass().getName() + " finder!");

			List<Program> items = null;
			try {
				items = curFinder.getMonitorItems();
			} catch (Exception exception) {
				Logger.getRootLogger().error("run " + curFinder.getClass().getName() + " finder error ocurred!"
						+ ExceptionUtils.getStackTrace(exception));
			}
			
			if (items == null || items.isEmpty()){
				continue;
			}
			Logger.getRootLogger().info("sendProgram number :  " + items.size());
			for (Program cur : items) {
				cur.setTrust(1);
				ProgramObj pobj = new ProgramObj();
				pobj.setCpname(cur.getCpname());
				pobj.setIp(cur.getIp());
				pobj.setPort(cur.getPort());
				pobj.setPath(cur.getPath());
				pobj.setType(cur.getType());
				pobj.setTrust(cur.getTrust());
				pobj.setFlags(cur.getFlags());
                pobj.setInfon(cur.getHeaders());
	    		//getMAC
				pobj.setMac(MCAgentConfig.getInstance().getMonitoredPointMAC());
	    		//get机房名称
				pobj.setHostroom(MCAgentConfig.getInstance().getEngineRoomName());

				//thrift 传输中不允许有 null 存在
				if (pobj.getFlags() == null) {
					pobj.setFlags(new LinkedList<String>());
				}
				if (pobj.getPath() == null) {
					pobj.setPath("");
				}

				sendProgram.add(pobj);
			}
		}
		return sendProgram;
	}
	
	
	public static FindBaseMonitorItemAbs getFindMonitor() {
		return findMonitor;
	}

	public static void setFindMonitor(FindBaseMonitorItemAbs findMonitor) {
		FinderThread.findMonitor = findMonitor;
	}


	public static FindLibMonitorItem getFindLib() {
		return findLib;
	}

	public static void setFindLib(FindLibMonitorItem findLib) {
		FinderThread.findLib = findLib;
	}

	
	private final byte[] lock = new byte[0];
	/****
	 * wlhu, 2014/10/27, 添加windows系统的基础监控
	 */
	@Override
	public void run() {
		List<Finder> finders = new LinkedList<Finder>();

		Properties props = System.getProperties();
		String osName = props.getProperty("os.name");
		
		if (osName.toLowerCase().contains("linux")) {
			finders.add(findMonitor);
			finders.add(new FindMonitorItemByShell());
		}else if (osName.toLowerCase().contains("mac")) {
			finders.add(findMonitor);
			finders.add(new FindMonitorItemByShell());
		} else if (osName.toLowerCase().contains("windows")) {
			finders.add(findMonitor);
			finders.add(new FindWinMonitorItem());
		}
		Filter filter = new Filter("");
		TrustJudgement trust = new TrustJudgement("");
		boolean notrun = true;
		
		long sleepTime = 60L * 1000 * MCAgentConfig.getInstance().getFind_interval();
		while (true) {
			try{
				if(!notrun){
					try {
						synchronized (lock) {
							lock.wait(sleepTime);
						}
					} catch (InterruptedException e) {
						Logger.getRootLogger().error(e.getMessage(),e);
					}
				}
				notrun = false;
				
				//查询需要添加的
				List<IItem> sendProgram = runFinder(finders, filter, trust);
				sendFindResult(filter,sendProgram);
				sendProgram.clear();
			}catch(Exception e){
				Logger.getRootLogger().error(e.getMessage(),e);
			}
		}
	}
}
